[project]
name = "arize-phoenix"
description = "AI Observability and Evaluation"
readme = "README.md"
requires-python = ">=3.8, <3.13"
license = "Elastic-2.0"
license-files = { paths = ["LICENSE", "IP_NOTICE"] }
keywords = [
  "Observability",
  "Monitoring",
  "Explainability",
]
authors = [
  { name = "Arize AI", email = "phoenix-devs@arize.com" },
]
classifiers = [
  "Programming Language :: Python",
  "Programming Language :: Python :: 3.8",
  "Programming Language :: Python :: 3.9",
  "Programming Language :: Python :: 3.10",
  "Programming Language :: Python :: 3.11",
  "Programming Language :: Python :: 3.12",
]
dependencies = [
  "scikit-learn",
  "numpy",
  "pandas",
  "jinja2",
  "umap-learn",
  "hdbscan>=0.8.33",
  "starlette",
  "uvicorn",
  "psutil",
  "strawberry-graphql==0.208.2",
  "pyarrow",
  "typing-extensions>=4.5; python_version<'3.12'",
  # A minimum version of typing-extensions==4.6.0 is needed to avoid this issue on Python 3.12: https://github.com/Azure/azure-sdk-for-python/issues/33442#issuecomment-1847886784
  "typing-extensions>=4.6; python_version>='3.12'",
  "scipy",
  "wrapt",
  "sortedcontainers",
  "protobuf>=3.20, <5.0",
  "ddsketch",
  "tqdm",
  "requests",
  "opentelemetry-sdk",
  "opentelemetry-proto",
  "opentelemetry-exporter-otlp",
  "openinference-semantic-conventions>=0.1.5",
  "openinference-instrumentation-langchain>=0.1.12",
  "openinference-instrumentation-llama-index>=1.2.0",
  "openinference-instrumentation-openai>=0.1.4",
]
dynamic = ["version"]

[project.optional-dependencies]
dev = [
  "gcsfs",
  "hatch",
  "jupyter",
  "nbqa",
  "ruff==0.3.0",
  "pandas-stubs<=2.0.2.230605",  # version 2.0.3.230814 is causing a dependency conflict.
  "pytest==7.4.4",
  "pytest-asyncio",
  "pytest-cov",
  "pytest-lazy-fixture",
  "strawberry-graphql[debug-server]==0.208.2",
  "pre-commit",
  "arize[AutoEmbeddings, LLM_Evaluation]",
  "llama-index>=0.10.3",
  "langchain>=0.0.334",
  "litellm>=1.0.3",
  "google-cloud-aiplatform>=1.3",
  "anthropic",
]
evals = [
  "arize-phoenix-evals>=0.3.0",
]
experimental = [
  "tenacity",
]
llama-index = [
  "llama-index==0.10.3",  # always pin to a version that keeps our notebooks working
  "llama-index-callbacks-arize-phoenix>=0.1.2",
  "openinference-instrumentation-llama-index>=1.2.0",
]

[project.urls]
Documentation = "https://docs.arize.com/phoenix/"
Issues = "https://github.com/Arize-ai/phoenix/issues"
Source = "https://github.com/Arize-ai/phoenix"

[tool.hatch.version]
path = "src/phoenix/version.py"

[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"

[tool.hatch.build.targets.wheel]
packages = ["src/phoenix"]
exclude = ["src/phoenix/evals/"]
artifacts = ["src/phoenix/server/static"]

[tool.hatch.build]
only-packages = true

[tool.hatch.build.targets.sdist]
exclude = ["src/phoenix/evals/", "packages/"]
artifacts = ["src/phoenix/server/static"]

[tool.hatch.envs.default]
dependencies = [
  "pandas==1.4.0",
  "pytest==7.4.4",
  "pytest-asyncio",
  "pytest-cov",
  "pytest-lazy-fixture",
  "arize",
  "litellm>=1.0.3",
  "openai>=1.0.0",
  "tenacity",
  "requests",
  "protobuf==3.20",  # version minimum (for tests)
  "responses",
  "tiktoken",
  "typing-extensions==4.5.0; python_version<'3.12'",
  "typing-extensions==4.6.0; python_version>='3.12'",
  "httpx", # For OpenAI testing
  "respx", # For OpenAI testing
  "nest-asyncio", # for executor testing
  "pyfakefs", # for experimental storage implementations
]

[tool.hatch.envs.type]
dependencies = [
  "mypy==1.5.1",
  "tenacity",
  "pandas-stubs<=2.0.2.230605",  # version 2.0.3.230814 is causing a dependency conflict.
  "types-psutil",
  "types-tqdm",
  "types-requests",
  "types-protobuf",
  "types-setuptools",
  "openai>=1.0.0",
  "litellm>=1.0.3",
]

[tool.hatch.envs.style]
detached = true
dependencies = [
  "ruff==0.3.0",
]

[tool.hatch.envs.notebooks]
detached = true
dependencies = [
  "jupyter",
]

[tool.hatch.envs.docs]
detached = true
dependencies = [
  "interrogate",
]

[tool.hatch.envs.default.scripts]
tests = "pytest {args}"
coverage = "pytest --cov-report=term-missing --cov-config=pyproject.toml --cov=src/phoenix --cov=tests {args}"

[[tool.hatch.envs.test.matrix]]
python = ["3.8", "3.12"]

[tool.pytest.ini_options]
asyncio_mode = "auto"
addopts = [
  "-rA",
  "--import-mode=importlib",
  "--doctest-modules",
]
testpaths = [
  "tests",
]

[tool.coverage.run]
branch = true
parallel = true
omit = [
  "**/__init__.py",
]

[tool.coverage.report]
fail_under=30
show_missing=true
sort="cover"
exclude_lines = [
  "no cov",
  "if __name__ == .__main__.:",
  "if TYPE_CHECKING:",
]

[tool.hatch.envs.type.scripts]
check = [
  "mypy .",
]

[tool.hatch.envs.style.scripts]
check = [
  "ruff format --check --diff .",
  "ruff check .",
]
fix = [
  "ruff format .",
  "ruff check --fix .",
]

[tool.hatch.envs.notebooks.scripts]
clean = [
  "jupyter nbconvert --ClearOutputPreprocessor.enabled=True --ClearMetadataPreprocessor.enabled=True --inplace **/*.ipynb **/internal/*.ipynb **/tracing/*.ipynb **/dolly-pythia-fine-tuned/*.ipynb",
]

[tool.hatch.envs.publish]
dependencies = [
  "check-wheel-contents",
  "twine",
]

[tool.hatch.envs.publish.scripts]
testpypi = [
  "check-wheel-contents dist/",
  "twine upload  --verbose --repository testpypi dist/*",
]
pypi = [
  "check-wheel-contents dist/",
  "twine upload --verbose dist/*",
]

[tool.hatch.envs.docs.scripts]
check = [
  "interrogate -vv src/",
]

[tool.hatch.envs.gql]
dependencies = [
  "strawberry-graphql[cli]==0.208.2",
  "requests",
]

[tool.hatch.envs.gql.scripts]
build = 'strawberry export-schema phoenix.server.api.schema:schema > app/schema.graphql'

[tool.hatch.envs.proto]
detached = true
dependencies = [
  "grpcio-tools==1.54.3",
  "mypy-protobuf==3.5.0",
]

[tool.hatch.envs.proto.scripts]
recompile = """
python -m grpc_tools.protoc -I src/phoenix/proto --python_out=src/phoenix --mypy_out=src/phoenix src/phoenix/proto/trace/v1/evaluation.proto
"""

[tool.interrogate]
fail-under = 0
# generate-badge = "badges/"
omit-covered-files = true
ignore-init-method = true
ignore-init-module = true
ignore-magic = false
ignore-semiprivate = false
ignore-private = false
ignore-property-decorators = false
ignore-module = false
ignore-nested-functions = false
ignore-nested-classes = false
ignore-setters = false

[tool.mypy]
plugins = ["strawberry.ext.mypy_plugin", "pydantic.mypy"]
disallow_untyped_calls = true
disallow_untyped_defs = true
disallow_incomplete_defs  = true
strict = true
exclude = [
  "packages/",
  "src/phoenix/evals/",
  "dist/",
  "scripts/data/",
  "sdist/",
  "tests/",
  "tutorials/",
]

[[tool.mypy.overrides]]
module = [
  "hdbscan",
  "umap",
  "numba.*",
  "scipy.*",
  "sklearn.*",
  "arize.*",
  "wrapt",
  "sortedcontainers",
  "langchain.*",
  "litellm",
  "nest_asyncio",
  "opentelemetry.*",
  "pyarrow",
]
ignore_missing_imports = true

[tool.ruff]
exclude = [
  "packages",
  "src/phoenix/evals/",
  "dist/",
  ".git",
  "__pycache__",
  "docs/source/conf.py",
  "*_pb2.py*",
  "*.pyi",
]
extend-include = ["*.ipynb"]
line-length = 100
target-version = "py38"

[tool.ruff.lint.per-file-ignores]
"*.ipynb" = ["E402", "E501"]

[tool.ruff.lint]
ignore-init-module-imports = true
select = ["E", "F", "W", "I"]

[tool.ruff.lint.isort]
force-single-line = false
